[iOS 11] 新フレームワークCore NFCを使ってNFCタグのデータを読み取ってみた #WWDC17
はじめに
こんにちは。モバイルアプリサービス部の平屋です。
iOS 11で追加されたフレームワークCore NFCを使って、NFCタグのデータを読み取る実装を試してみましたので紹介します。
本記事は Apple からベータ版として公開されているドキュメントを情報源としています。 そのため、正式版と異なる情報になる可能性があります。ご留意の上、お読みください。
検証環境
- Mac
- macOS Sierra 10.12.5
- Xcode Version 9.0 beta (9M136h)
- iPhone 7
- iOS 11.0 (15A5278f)
Core NFC
NFCタグを検出し、NDEF(NFC Data Exchange Format)データを含むメッセージを読み取るためのフレームワークです。
NFCタグとCore NFCを組み合わせて使うと、以下のような機能を実現できます。
- 店舗内の製品に関する情報をユーザーに提供する
- 博物館の展示物に関する情報をユーザーに提供する
NFCタグ
検証用に、愛三電機でシールタイプのNFCタグを購入しました。サイズは100円玉ぐらいで、型番は「SC3002991」です。
裏はこんな感じになってます。
NDEFデータをNFCタグに書き込む
Core NFCのリファレンスによると、Core NFCはNDEF(NFC Data Exchange Format)というフォーマットのデータを扱うことができます。
今回は、Android端末(Nexus 5)とNFC NDEF Writerを使用して、文字列「https://dev.classmethod.jp」をNFCタグに書き込みました。
実装
NFC Tag Reading を有効にする
以下の操作を行い、アプリで使用するApp IDのNFC Tag Readingを有効にします。
- developer.apple.com > Account > Certificates, Identifiers & Profiles > App IDsを開く
- アプリで使用するApp IDを選択する
- App Services > NFC Tag Reading を有効にする
entitlementsファイルに値を追加する
<ProjectName>.entitlementsファイルにcom.apple.developer.nfc.readersession.formatsキーと値を追加します。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.developer.nfc.readersession.formats</key> <array> <string>NDEF</string> </array> </dict> </plist>
プロジェクトにentitlementsファイルがなくて、新規でentitlementsファイルを追加しなければならない場合は、何か適当なCapabilitiesを追加してentitlementsファイルをXcodeに追加させるのが楽もしれません。
Info.plistファイルに値を追加する
Info.plistファイルにNFCReaderUsageDescriptionキーと値(NFCReaderの使用目的)を追加します。
... <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> ... <key>NFCReaderUsageDescription</key> <string>We are going to use you NFC!</string> </dict> </plist>
NFCNDEFReaderSessionを使用した実装を追加する
NFCNDEFReaderSessionを作成してbegin()
を呼ぶと、読み取りのセッションが開始します。
import UIKit import CoreNFC class ViewController: UIViewController { var session: NFCNDEFReaderSession! override func viewDidLoad() { super.viewDidLoad() session = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: true) session.begin() } }
読み取りが完了すると、NFCNDEFReaderSessionDelegateのreaderSession(_:didDetectNDEFs:)
メソッドが呼ばます。
タグに書き込まれたデータはmessages引数から取得できます。AndroidアプリNFC NDEF Writeで書き込んだデータは、NFCNDEFPayloadのpayload
プロパティに入っていました。
extension ViewController: NFCNDEFReaderSessionDelegate { func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) { for message in messages { for record in message.records { if let type = String.init(data: record.type, encoding: .utf8) { print("type: \(type)") } if let identifier = String.init(data: record.identifier, encoding: .utf8) { print("identifier: \(identifier)") } if let payload = String.init(data: record.payload, encoding: .utf8) { print("payload: \(payload)") } } } } public func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) { print(#function, error) } }
さいごに
本記事では、Core NFCを使って、NFCタグのデータを読み取る実装を紹介しました。
設定や実装はそんなに時間がかかりませんでしたが、読み取りの動作確認に時間がかかってしまいました。(読み取りが上手くいかず、タイムアウトになる)
最終的に、iPhoneの上端をNFCタグに近づけると、読み取りが上手くいきました。